#ifndef PLCSCOPE_H_
#define PLCSCOPE_H_

#include <vector>
#include <string>

// #include <plc2llvm/PLCScope.h>
#include <plc2llvm/PLCSymbols/ImportScope.h>
#include <plc2llvm/PLCSymbolTable.h>
#include <plc2llvm/PLCSymbols/PLCSymbol.h>

class PLCSymbolTable;
class PLCSymbol;

class PLCScope {
private:
    ImportScope* importSymbol;
    PLCSymbolTable* symbolTable;
    PLCScope* parentScope;
    std::vector<PLCScope*> childScopes;
    std::vector<PLCScope*> usingNamespaceList;

public:
    //symbol table 在PLCScope里隐式构造，不与用户显式接触
    explicit PLCScope(ImportScope* importScope, PLCScope* parentScope);

    //父作用域默认为当前顶作用域
    explicit PLCScope(ImportScope* importScope);

    //引入符号和父作用域全为nullptr，全局作用域使用
    explicit PLCScope();

    ~PLCScope() {}

    PLCScope(const PLCScope& scope) = delete;
    PLCScope& operator=(const PLCScope& scope) = delete;

    PLCScope(PLCScope&& scope) = default;
    PLCScope& operator=(PLCScope&& scope) = delete;


    void setImportSymbol(ImportScope* importSymbol);
    ImportScope* getImportSymbol();

    void setSymbolTable(PLCSymbolTable* symbolTable);
    PLCSymbolTable* getSymbolTable();

    void setParentScope(PLCScope* parentScope);
    PLCScope* getParentScope();

    void addChildScope(PLCScope* childScope);
    std::vector<PLCScope*>& getChildScopes();

    //TODO:修改查找策略时此函数也需要修改，这个函数并非纯粹地做了添加命名空间一件事
    void addUsingNamespaceList(PLCScope* usedNamespace);
    std::vector<PLCScope*>& getUsingNamespaceList();
    void addLocalSymbol(PLCSymbol* localSymbol);
 
    //TODO:修改查找策略
    [[deprecated("use findSymbolFromLocal instead")]]
    PLCSymbol* findSymbolByNameFromLocal(std::string name);

    [[deprecated("use findSymbolFromAll instead")]]
    PLCSymbol* findSymbolByNameFromAll(std::string name);

    //新算法
    //在仅仅本作用域内按名称寻找符号
    PLCSymbol* findSymbolFromLocal(std::string name);

    //在本作用域和与本作用域关联的位置查找 TODO:没有处理查找重复的作用域的问题，或许不处理为好
    PLCSymbol* findSymbolFromAll(std::string name);

};




#endif